#ifndef RENDERER_INCLUDED
#define RENDERER_INCLUDED

#pragma once

#include "vec2.h"
#include "vec3.h"
#include "com_ptr.h"
#include <d3d11.h>
#include <list>
#include "VertexShaderBinary.h"
#include "PixelShaderBinary.h"
#include "TextureCache.h"

class Renderer
{
public:

	struct Vertex
	{
		vec3f Position;
		vec2f TexCoord;

		Vertex(const vec2f& pos, const vec2f& tex);
	};

	Renderer(const std::string& defaultps, const std::string& defaultvs);
	com_ptr<ID3D11Device> GetDevice() const;
	com_ptr<ID3D11DeviceContext> GetDeviceContext() const;

	// scoped object to call start/end of render
	struct SpriteBatch
	{
		SpriteBatch(Renderer& renderer);
		~SpriteBatch();
	private:
		Renderer& m_Renderer;
	};

	void RenderTriangle(const vec2f& a, const vec2f& ta,
							   const vec2f& b, const vec2f& tb,
							   const vec2f& c, const vec2f& tc,
							   const std::string& texturepath);

	void PreloadTextureList(const std::list<std::string>& list);
	void LoadTexture(const std::string& path);

private:
	void StartRender();
	void EndRender();
	void Render();

	static const unsigned int DeviceFlags = D3D11_CREATE_DEVICE_DEBUG;
	static const unsigned int VerticesAmount = 300;

	com_ptr<ID3D11Device> m_Device;
	com_ptr<ID3D11DeviceContext> m_Context;

	VertexShaderBinary m_VertexShaderBinary;
	PixelShaderBinary m_PixelShaderBinary;

	com_ptr<ID3D11PixelShader> m_DefaultPixelShader;
	com_ptr<ID3D11VertexShader> m_DefaultVertexShader;

	com_ptr<ID3D11Buffer> m_VertexBuffer;
	com_ptr<ID3D11InputLayout> m_InputLayout;

	bool m_RenderStarted;
	int m_NumRendered;
	Vertex* m_VertexBufferPointer;
	std::string m_CurrentTexture;

	TextureCache m_Cache;
};

#endif